﻿using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using élénkPróbája.extentions;
using élénkPróbája.Test.dto;
using élénkPróbája.Test.extention;
using élénkPróbája.validators;

namespace élénkPróbája.Test
{
    [TestClass]
    public class LengthValidatorTests
    { 
		public LengthValidatorTests()
        {
            CultureScope.SetDefaultCulture();
        }

        [TestMethod] 
        public void When_the_text_is_between_the_range_specified_then_the_validator_should_pass()
        {
            var validator = new TestValidator(v => v.RuleFor(x => x.Name).Length(1, 10));
            var result = validator.Validate(new Company { Name = "Test" });
            result.IsValid.ShouldBeTrue();
        }

        [TestMethod]
        public void When_the_text_is_smaller_than_the_range_then_the_validator_should_fail()
        {
            var validator = new TestValidator(v => v.RuleFor(x => x.Name).Length(5, 10));
            var result = validator.Validate(new Company { Name = "Test" });
            result.IsValid.ShouldBeFalse();
        }
        
        [TestMethod]
        public void When_the_text_is_larger_than_the_range_then_the_validator_should_fail()
        {
            var validator = new TestValidator(v => v.RuleFor(x => x.Name).Length(1, 2));
            var result = validator.Validate(new Company { Name = "Test" });
            result.IsValid.ShouldBeFalse();
        }
        
        [TestMethod]
        public void When_the_text_is_exactly_the_size_of_the_upper_bound_then_the_validator_should_pass()
        {
            var validator = new TestValidator(v => v.RuleFor(x => x.Name).Length(1, 4));
            var result = validator.Validate(new Company { Name = "Test" });
            result.IsValid.ShouldBeTrue();
        }
        
        [TestMethod]
        public void When_the_text_is_exactly_the_size_of_the_lower_bound_then_the_validator_should_pass()
        {
            var validator = new TestValidator(v => v.RuleFor(x => x.Name).Length(4, 5));
            var result = validator.Validate(new Company { Name = "Test" });
            result.IsValid.ShouldBeTrue();
        }
        
        [TestMethod]
        public void When_the_max_is_smaller_than_the_min_then_the_validator_should_throw()
        {
            MyAssert.Throws<ArgumentOutOfRangeException>(() =>
                new TestValidator(v => v.RuleFor(x => x.Name).Length(10, 1)));
        }

        [TestMethod]
        public void When_the_validator_fails_the_error_message_should_be_set()
        {
            var validator = new TestValidator(v => v.RuleFor(x => x.Name).Length(1, 2));
            var result = validator.Validate(new Company { Name = "Gire and gimble in the wabe" });
            result.Errors.Single().ErrorMessage.ShouldEqual("'' must be between 1 and 2 characters. You entered 27 characters.");
        }

        [TestMethod]
        public void Min_and_max_properties_should_be_set()
        {
            var validator = new LengthValidator(1, 5);
            validator.Min.ShouldEqual(1);
            validator.Max.ShouldEqual(5);
        }

        [TestMethod]
        public void When_input_is_null_then_the_validator_should_pass()
        {
            var validator = new TestValidator {
                v => v.RuleFor(x => x.Name).Length(5)
            };

            var result = validator.Validate(new Company { Name = null });
            result.IsValid.ShouldBeTrue();
        }
    }
}
